aiecs 1.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiecs/__init__.py +72 -0
- aiecs/__main__.py +41 -0
- aiecs/aiecs_client.py +469 -0
- aiecs/application/__init__.py +10 -0
- aiecs/application/executors/__init__.py +10 -0
- aiecs/application/executors/operation_executor.py +363 -0
- aiecs/application/knowledge_graph/__init__.py +7 -0
- aiecs/application/knowledge_graph/builder/__init__.py +37 -0
- aiecs/application/knowledge_graph/builder/document_builder.py +375 -0
- aiecs/application/knowledge_graph/builder/graph_builder.py +356 -0
- aiecs/application/knowledge_graph/builder/schema_mapping.py +531 -0
- aiecs/application/knowledge_graph/builder/structured_pipeline.py +443 -0
- aiecs/application/knowledge_graph/builder/text_chunker.py +319 -0
- aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
- aiecs/application/knowledge_graph/extractors/base.py +100 -0
- aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +327 -0
- aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +349 -0
- aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +244 -0
- aiecs/application/knowledge_graph/fusion/__init__.py +23 -0
- aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +387 -0
- aiecs/application/knowledge_graph/fusion/entity_linker.py +343 -0
- aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +580 -0
- aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +189 -0
- aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
- aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +344 -0
- aiecs/application/knowledge_graph/pattern_matching/query_executor.py +378 -0
- aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
- aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +199 -0
- aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
- aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
- aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +347 -0
- aiecs/application/knowledge_graph/reasoning/inference_engine.py +504 -0
- aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +167 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +630 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +654 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +477 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +390 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +217 -0
- aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +169 -0
- aiecs/application/knowledge_graph/reasoning/query_planner.py +872 -0
- aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +554 -0
- aiecs/application/knowledge_graph/retrieval/__init__.py +19 -0
- aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +596 -0
- aiecs/application/knowledge_graph/search/__init__.py +59 -0
- aiecs/application/knowledge_graph/search/hybrid_search.py +423 -0
- aiecs/application/knowledge_graph/search/reranker.py +295 -0
- aiecs/application/knowledge_graph/search/reranker_strategies.py +553 -0
- aiecs/application/knowledge_graph/search/text_similarity.py +398 -0
- aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
- aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +329 -0
- aiecs/application/knowledge_graph/traversal/path_scorer.py +269 -0
- aiecs/application/knowledge_graph/validators/__init__.py +13 -0
- aiecs/application/knowledge_graph/validators/relation_validator.py +189 -0
- aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
- aiecs/application/knowledge_graph/visualization/graph_visualizer.py +321 -0
- aiecs/common/__init__.py +9 -0
- aiecs/common/knowledge_graph/__init__.py +17 -0
- aiecs/common/knowledge_graph/runnable.py +484 -0
- aiecs/config/__init__.py +16 -0
- aiecs/config/config.py +498 -0
- aiecs/config/graph_config.py +137 -0
- aiecs/config/registry.py +23 -0
- aiecs/core/__init__.py +46 -0
- aiecs/core/interface/__init__.py +34 -0
- aiecs/core/interface/execution_interface.py +152 -0
- aiecs/core/interface/storage_interface.py +171 -0
- aiecs/domain/__init__.py +289 -0
- aiecs/domain/agent/__init__.py +189 -0
- aiecs/domain/agent/base_agent.py +697 -0
- aiecs/domain/agent/exceptions.py +103 -0
- aiecs/domain/agent/graph_aware_mixin.py +559 -0
- aiecs/domain/agent/hybrid_agent.py +490 -0
- aiecs/domain/agent/integration/__init__.py +26 -0
- aiecs/domain/agent/integration/context_compressor.py +222 -0
- aiecs/domain/agent/integration/context_engine_adapter.py +252 -0
- aiecs/domain/agent/integration/retry_policy.py +219 -0
- aiecs/domain/agent/integration/role_config.py +213 -0
- aiecs/domain/agent/knowledge_aware_agent.py +646 -0
- aiecs/domain/agent/lifecycle.py +296 -0
- aiecs/domain/agent/llm_agent.py +300 -0
- aiecs/domain/agent/memory/__init__.py +12 -0
- aiecs/domain/agent/memory/conversation.py +197 -0
- aiecs/domain/agent/migration/__init__.py +14 -0
- aiecs/domain/agent/migration/conversion.py +160 -0
- aiecs/domain/agent/migration/legacy_wrapper.py +90 -0
- aiecs/domain/agent/models.py +317 -0
- aiecs/domain/agent/observability.py +407 -0
- aiecs/domain/agent/persistence.py +289 -0
- aiecs/domain/agent/prompts/__init__.py +29 -0
- aiecs/domain/agent/prompts/builder.py +161 -0
- aiecs/domain/agent/prompts/formatters.py +189 -0
- aiecs/domain/agent/prompts/template.py +255 -0
- aiecs/domain/agent/registry.py +260 -0
- aiecs/domain/agent/tool_agent.py +257 -0
- aiecs/domain/agent/tools/__init__.py +12 -0
- aiecs/domain/agent/tools/schema_generator.py +221 -0
- aiecs/domain/community/__init__.py +155 -0
- aiecs/domain/community/agent_adapter.py +477 -0
- aiecs/domain/community/analytics.py +481 -0
- aiecs/domain/community/collaborative_workflow.py +642 -0
- aiecs/domain/community/communication_hub.py +645 -0
- aiecs/domain/community/community_builder.py +320 -0
- aiecs/domain/community/community_integration.py +800 -0
- aiecs/domain/community/community_manager.py +813 -0
- aiecs/domain/community/decision_engine.py +879 -0
- aiecs/domain/community/exceptions.py +225 -0
- aiecs/domain/community/models/__init__.py +33 -0
- aiecs/domain/community/models/community_models.py +268 -0
- aiecs/domain/community/resource_manager.py +457 -0
- aiecs/domain/community/shared_context_manager.py +603 -0
- aiecs/domain/context/__init__.py +58 -0
- aiecs/domain/context/context_engine.py +989 -0
- aiecs/domain/context/conversation_models.py +354 -0
- aiecs/domain/context/graph_memory.py +467 -0
- aiecs/domain/execution/__init__.py +12 -0
- aiecs/domain/execution/model.py +57 -0
- aiecs/domain/knowledge_graph/__init__.py +19 -0
- aiecs/domain/knowledge_graph/models/__init__.py +52 -0
- aiecs/domain/knowledge_graph/models/entity.py +130 -0
- aiecs/domain/knowledge_graph/models/evidence.py +194 -0
- aiecs/domain/knowledge_graph/models/inference_rule.py +186 -0
- aiecs/domain/knowledge_graph/models/path.py +179 -0
- aiecs/domain/knowledge_graph/models/path_pattern.py +173 -0
- aiecs/domain/knowledge_graph/models/query.py +272 -0
- aiecs/domain/knowledge_graph/models/query_plan.py +187 -0
- aiecs/domain/knowledge_graph/models/relation.py +136 -0
- aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
- aiecs/domain/knowledge_graph/schema/entity_type.py +135 -0
- aiecs/domain/knowledge_graph/schema/graph_schema.py +271 -0
- aiecs/domain/knowledge_graph/schema/property_schema.py +155 -0
- aiecs/domain/knowledge_graph/schema/relation_type.py +171 -0
- aiecs/domain/knowledge_graph/schema/schema_manager.py +496 -0
- aiecs/domain/knowledge_graph/schema/type_enums.py +205 -0
- aiecs/domain/task/__init__.py +13 -0
- aiecs/domain/task/dsl_processor.py +613 -0
- aiecs/domain/task/model.py +62 -0
- aiecs/domain/task/task_context.py +268 -0
- aiecs/infrastructure/__init__.py +24 -0
- aiecs/infrastructure/graph_storage/__init__.py +11 -0
- aiecs/infrastructure/graph_storage/base.py +601 -0
- aiecs/infrastructure/graph_storage/batch_operations.py +449 -0
- aiecs/infrastructure/graph_storage/cache.py +429 -0
- aiecs/infrastructure/graph_storage/distributed.py +226 -0
- aiecs/infrastructure/graph_storage/error_handling.py +390 -0
- aiecs/infrastructure/graph_storage/graceful_degradation.py +306 -0
- aiecs/infrastructure/graph_storage/health_checks.py +378 -0
- aiecs/infrastructure/graph_storage/in_memory.py +514 -0
- aiecs/infrastructure/graph_storage/index_optimization.py +483 -0
- aiecs/infrastructure/graph_storage/lazy_loading.py +410 -0
- aiecs/infrastructure/graph_storage/metrics.py +357 -0
- aiecs/infrastructure/graph_storage/migration.py +413 -0
- aiecs/infrastructure/graph_storage/pagination.py +471 -0
- aiecs/infrastructure/graph_storage/performance_monitoring.py +466 -0
- aiecs/infrastructure/graph_storage/postgres.py +871 -0
- aiecs/infrastructure/graph_storage/query_optimizer.py +635 -0
- aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
- aiecs/infrastructure/graph_storage/sqlite.py +623 -0
- aiecs/infrastructure/graph_storage/streaming.py +495 -0
- aiecs/infrastructure/messaging/__init__.py +13 -0
- aiecs/infrastructure/messaging/celery_task_manager.py +383 -0
- aiecs/infrastructure/messaging/websocket_manager.py +298 -0
- aiecs/infrastructure/monitoring/__init__.py +34 -0
- aiecs/infrastructure/monitoring/executor_metrics.py +174 -0
- aiecs/infrastructure/monitoring/global_metrics_manager.py +213 -0
- aiecs/infrastructure/monitoring/structured_logger.py +48 -0
- aiecs/infrastructure/monitoring/tracing_manager.py +410 -0
- aiecs/infrastructure/persistence/__init__.py +24 -0
- aiecs/infrastructure/persistence/context_engine_client.py +187 -0
- aiecs/infrastructure/persistence/database_manager.py +333 -0
- aiecs/infrastructure/persistence/file_storage.py +754 -0
- aiecs/infrastructure/persistence/redis_client.py +220 -0
- aiecs/llm/__init__.py +86 -0
- aiecs/llm/callbacks/__init__.py +11 -0
- aiecs/llm/callbacks/custom_callbacks.py +264 -0
- aiecs/llm/client_factory.py +420 -0
- aiecs/llm/clients/__init__.py +33 -0
- aiecs/llm/clients/base_client.py +193 -0
- aiecs/llm/clients/googleai_client.py +181 -0
- aiecs/llm/clients/openai_client.py +131 -0
- aiecs/llm/clients/vertex_client.py +437 -0
- aiecs/llm/clients/xai_client.py +184 -0
- aiecs/llm/config/__init__.py +51 -0
- aiecs/llm/config/config_loader.py +275 -0
- aiecs/llm/config/config_validator.py +236 -0
- aiecs/llm/config/model_config.py +151 -0
- aiecs/llm/utils/__init__.py +10 -0
- aiecs/llm/utils/validate_config.py +91 -0
- aiecs/main.py +363 -0
- aiecs/scripts/__init__.py +3 -0
- aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
- aiecs/scripts/aid/__init__.py +19 -0
- aiecs/scripts/aid/version_manager.py +215 -0
- aiecs/scripts/dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md +242 -0
- aiecs/scripts/dependance_check/README_DEPENDENCY_CHECKER.md +310 -0
- aiecs/scripts/dependance_check/__init__.py +17 -0
- aiecs/scripts/dependance_check/dependency_checker.py +938 -0
- aiecs/scripts/dependance_check/dependency_fixer.py +391 -0
- aiecs/scripts/dependance_check/download_nlp_data.py +396 -0
- aiecs/scripts/dependance_check/quick_dependency_check.py +270 -0
- aiecs/scripts/dependance_check/setup_nlp_data.sh +217 -0
- aiecs/scripts/dependance_patch/__init__.py +7 -0
- aiecs/scripts/dependance_patch/fix_weasel/README_WEASEL_PATCH.md +126 -0
- aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
- aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.py +128 -0
- aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.sh +82 -0
- aiecs/scripts/dependance_patch/fix_weasel/patch_weasel_library.sh +188 -0
- aiecs/scripts/dependance_patch/fix_weasel/run_weasel_patch.sh +41 -0
- aiecs/scripts/tools_develop/README.md +449 -0
- aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
- aiecs/scripts/tools_develop/__init__.py +21 -0
- aiecs/scripts/tools_develop/check_type_annotations.py +259 -0
- aiecs/scripts/tools_develop/validate_tool_schemas.py +422 -0
- aiecs/scripts/tools_develop/verify_tools.py +356 -0
- aiecs/tasks/__init__.py +1 -0
- aiecs/tasks/worker.py +172 -0
- aiecs/tools/__init__.py +299 -0
- aiecs/tools/apisource/__init__.py +99 -0
- aiecs/tools/apisource/intelligence/__init__.py +19 -0
- aiecs/tools/apisource/intelligence/data_fusion.py +381 -0
- aiecs/tools/apisource/intelligence/query_analyzer.py +413 -0
- aiecs/tools/apisource/intelligence/search_enhancer.py +388 -0
- aiecs/tools/apisource/monitoring/__init__.py +9 -0
- aiecs/tools/apisource/monitoring/metrics.py +303 -0
- aiecs/tools/apisource/providers/__init__.py +115 -0
- aiecs/tools/apisource/providers/base.py +664 -0
- aiecs/tools/apisource/providers/census.py +401 -0
- aiecs/tools/apisource/providers/fred.py +564 -0
- aiecs/tools/apisource/providers/newsapi.py +412 -0
- aiecs/tools/apisource/providers/worldbank.py +357 -0
- aiecs/tools/apisource/reliability/__init__.py +12 -0
- aiecs/tools/apisource/reliability/error_handler.py +375 -0
- aiecs/tools/apisource/reliability/fallback_strategy.py +391 -0
- aiecs/tools/apisource/tool.py +850 -0
- aiecs/tools/apisource/utils/__init__.py +9 -0
- aiecs/tools/apisource/utils/validators.py +338 -0
- aiecs/tools/base_tool.py +201 -0
- aiecs/tools/docs/__init__.py +121 -0
- aiecs/tools/docs/ai_document_orchestrator.py +599 -0
- aiecs/tools/docs/ai_document_writer_orchestrator.py +2403 -0
- aiecs/tools/docs/content_insertion_tool.py +1333 -0
- aiecs/tools/docs/document_creator_tool.py +1317 -0
- aiecs/tools/docs/document_layout_tool.py +1166 -0
- aiecs/tools/docs/document_parser_tool.py +994 -0
- aiecs/tools/docs/document_writer_tool.py +1818 -0
- aiecs/tools/knowledge_graph/__init__.py +17 -0
- aiecs/tools/knowledge_graph/graph_reasoning_tool.py +734 -0
- aiecs/tools/knowledge_graph/graph_search_tool.py +923 -0
- aiecs/tools/knowledge_graph/kg_builder_tool.py +476 -0
- aiecs/tools/langchain_adapter.py +542 -0
- aiecs/tools/schema_generator.py +275 -0
- aiecs/tools/search_tool/__init__.py +100 -0
- aiecs/tools/search_tool/analyzers.py +589 -0
- aiecs/tools/search_tool/cache.py +260 -0
- aiecs/tools/search_tool/constants.py +128 -0
- aiecs/tools/search_tool/context.py +216 -0
- aiecs/tools/search_tool/core.py +749 -0
- aiecs/tools/search_tool/deduplicator.py +123 -0
- aiecs/tools/search_tool/error_handler.py +271 -0
- aiecs/tools/search_tool/metrics.py +371 -0
- aiecs/tools/search_tool/rate_limiter.py +178 -0
- aiecs/tools/search_tool/schemas.py +277 -0
- aiecs/tools/statistics/__init__.py +80 -0
- aiecs/tools/statistics/ai_data_analysis_orchestrator.py +643 -0
- aiecs/tools/statistics/ai_insight_generator_tool.py +505 -0
- aiecs/tools/statistics/ai_report_orchestrator_tool.py +694 -0
- aiecs/tools/statistics/data_loader_tool.py +564 -0
- aiecs/tools/statistics/data_profiler_tool.py +658 -0
- aiecs/tools/statistics/data_transformer_tool.py +573 -0
- aiecs/tools/statistics/data_visualizer_tool.py +495 -0
- aiecs/tools/statistics/model_trainer_tool.py +487 -0
- aiecs/tools/statistics/statistical_analyzer_tool.py +459 -0
- aiecs/tools/task_tools/__init__.py +86 -0
- aiecs/tools/task_tools/chart_tool.py +732 -0
- aiecs/tools/task_tools/classfire_tool.py +922 -0
- aiecs/tools/task_tools/image_tool.py +447 -0
- aiecs/tools/task_tools/office_tool.py +684 -0
- aiecs/tools/task_tools/pandas_tool.py +635 -0
- aiecs/tools/task_tools/report_tool.py +635 -0
- aiecs/tools/task_tools/research_tool.py +392 -0
- aiecs/tools/task_tools/scraper_tool.py +715 -0
- aiecs/tools/task_tools/stats_tool.py +688 -0
- aiecs/tools/temp_file_manager.py +130 -0
- aiecs/tools/tool_executor/__init__.py +37 -0
- aiecs/tools/tool_executor/tool_executor.py +881 -0
- aiecs/utils/LLM_output_structor.py +445 -0
- aiecs/utils/__init__.py +34 -0
- aiecs/utils/base_callback.py +47 -0
- aiecs/utils/cache_provider.py +695 -0
- aiecs/utils/execution_utils.py +184 -0
- aiecs/utils/logging.py +1 -0
- aiecs/utils/prompt_loader.py +14 -0
- aiecs/utils/token_usage_repository.py +323 -0
- aiecs/ws/__init__.py +0 -0
- aiecs/ws/socket_server.py +52 -0
- aiecs-1.5.1.dist-info/METADATA +608 -0
- aiecs-1.5.1.dist-info/RECORD +302 -0
- aiecs-1.5.1.dist-info/WHEEL +5 -0
- aiecs-1.5.1.dist-info/entry_points.txt +10 -0
- aiecs-1.5.1.dist-info/licenses/LICENSE +225 -0
- aiecs-1.5.1.dist-info/top_level.txt +1 -0
aiecs/__init__.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AIECS - AI Execute Services
|
|
3
|
+
|
|
4
|
+
A powerful Python middleware framework for building AI-powered applications
|
|
5
|
+
with tool orchestration, task execution, and multi-provider LLM support.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "1.5.1"
|
|
9
|
+
__author__ = "AIECS Team"
|
|
10
|
+
__email__ = "iretbl@gmail.com"
|
|
11
|
+
|
|
12
|
+
# Core imports - these should work without configuration
|
|
13
|
+
from .aiecs_client import (
|
|
14
|
+
AIECS,
|
|
15
|
+
create_aiecs_client,
|
|
16
|
+
create_simple_client,
|
|
17
|
+
create_full_client,
|
|
18
|
+
)
|
|
19
|
+
from .domain.task.task_context import TaskContext
|
|
20
|
+
|
|
21
|
+
# Configuration
|
|
22
|
+
from .config.config import get_settings, validate_required_settings
|
|
23
|
+
|
|
24
|
+
# Tool system - safe to import
|
|
25
|
+
from .tools import discover_tools, list_tools, get_tool, register_tool
|
|
26
|
+
|
|
27
|
+
# Infrastructure components - can be imported safely (for advanced usage)
|
|
28
|
+
# These classes only require configuration when actually used
|
|
29
|
+
from .infrastructure.persistence.database_manager import DatabaseManager
|
|
30
|
+
from .infrastructure.messaging.celery_task_manager import CeleryTaskManager
|
|
31
|
+
|
|
32
|
+
# LLM providers
|
|
33
|
+
from .llm.client_factory import LLMClientFactory, AIProvider
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_fastapi_app():
|
|
37
|
+
"""
|
|
38
|
+
Get the FastAPI application instance (lazy loading)
|
|
39
|
+
Only loads when explicitly requested to avoid import-time configuration validation
|
|
40
|
+
"""
|
|
41
|
+
from .main import app
|
|
42
|
+
|
|
43
|
+
return app
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
# Core API
|
|
48
|
+
"AIECS",
|
|
49
|
+
"create_aiecs_client",
|
|
50
|
+
"create_simple_client",
|
|
51
|
+
"create_full_client",
|
|
52
|
+
"TaskContext",
|
|
53
|
+
# FastAPI application (lazy loading)
|
|
54
|
+
"get_fastapi_app",
|
|
55
|
+
# Tool system
|
|
56
|
+
"discover_tools",
|
|
57
|
+
"list_tools",
|
|
58
|
+
"get_tool",
|
|
59
|
+
"register_tool",
|
|
60
|
+
# Configuration
|
|
61
|
+
"get_settings",
|
|
62
|
+
"validate_required_settings",
|
|
63
|
+
# Infrastructure (advanced)
|
|
64
|
+
"DatabaseManager",
|
|
65
|
+
"CeleryTaskManager",
|
|
66
|
+
"LLMClientFactory",
|
|
67
|
+
"AIProvider",
|
|
68
|
+
# Metadata
|
|
69
|
+
"__version__",
|
|
70
|
+
"__author__",
|
|
71
|
+
"__email__",
|
|
72
|
+
]
|
aiecs/__main__.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AIECS main entry point for command line execution
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
"""Main entry point for AIECS CLI"""
|
|
11
|
+
# Add the parent directory to the Python path to ensure imports work
|
|
12
|
+
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
13
|
+
if parent_dir not in sys.path:
|
|
14
|
+
sys.path.insert(0, parent_dir)
|
|
15
|
+
|
|
16
|
+
# Import and run uvicorn
|
|
17
|
+
import uvicorn
|
|
18
|
+
from aiecs.main import app
|
|
19
|
+
from aiecs.ws.socket_server import sio
|
|
20
|
+
import socketio
|
|
21
|
+
|
|
22
|
+
# Create the combined Socket.IO + FastAPI app
|
|
23
|
+
socket_app = socketio.ASGIApp(sio, other_asgi_app=app)
|
|
24
|
+
|
|
25
|
+
# Get port from environment or use default
|
|
26
|
+
port = int(os.environ.get("PORT", 8000))
|
|
27
|
+
|
|
28
|
+
print(f"Starting AIECS server on port {port}...")
|
|
29
|
+
|
|
30
|
+
# Run the application with Socket.IO support
|
|
31
|
+
uvicorn.run(
|
|
32
|
+
socket_app,
|
|
33
|
+
host="0.0.0.0",
|
|
34
|
+
port=port,
|
|
35
|
+
log_level="info",
|
|
36
|
+
reload=bool(os.environ.get("RELOAD", False)),
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
main()
|
aiecs/aiecs_client.py
ADDED
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AIECS Client - Main API for programmatic usage of AI Execute Services
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Dict, Any, Optional, List
|
|
8
|
+
from contextlib import asynccontextmanager
|
|
9
|
+
|
|
10
|
+
# Import core components
|
|
11
|
+
from aiecs.config.config import get_settings, validate_required_settings
|
|
12
|
+
from aiecs.domain.task.task_context import TaskContext
|
|
13
|
+
from aiecs.tools import discover_tools, list_tools, get_tool
|
|
14
|
+
from aiecs.llm.client_factory import (
|
|
15
|
+
LLMClientFactory,
|
|
16
|
+
LLMClientManager,
|
|
17
|
+
AIProvider,
|
|
18
|
+
)
|
|
19
|
+
from aiecs.llm.clients.base_client import LLMMessage
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class AIECS:
|
|
25
|
+
"""
|
|
26
|
+
Main AIECS client for programmatic usage
|
|
27
|
+
|
|
28
|
+
This class provides a high-level API for:
|
|
29
|
+
- Executing tasks with AI providers
|
|
30
|
+
- Managing tool orchestration
|
|
31
|
+
- Configuration management
|
|
32
|
+
|
|
33
|
+
Two operation modes:
|
|
34
|
+
- Simple mode: Tools and basic AI functionality (no database/Celery)
|
|
35
|
+
- Full mode: Complete infrastructure (requires database/Redis)
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, config: Optional[Dict[str, Any]] = None, mode: str = "simple"):
|
|
39
|
+
"""
|
|
40
|
+
Initialize AIECS client
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
config: Optional configuration override
|
|
44
|
+
mode: Operation mode - "simple" or "full"
|
|
45
|
+
"""
|
|
46
|
+
self.settings = get_settings()
|
|
47
|
+
self.config = config or {}
|
|
48
|
+
self.mode = mode
|
|
49
|
+
|
|
50
|
+
# Core components (loaded based on mode)
|
|
51
|
+
self.db_manager = None
|
|
52
|
+
self.task_manager = None
|
|
53
|
+
self.operation_executor = None
|
|
54
|
+
self.llm_manager = None
|
|
55
|
+
|
|
56
|
+
# State
|
|
57
|
+
self._initialized = False
|
|
58
|
+
self._tools_discovered = False
|
|
59
|
+
|
|
60
|
+
async def initialize(self):
|
|
61
|
+
"""Initialize AIECS services based on mode"""
|
|
62
|
+
if self._initialized:
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
logger.info(f"Initializing AIECS client in {self.mode} mode...")
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
# Always discover tools
|
|
69
|
+
if not self._tools_discovered:
|
|
70
|
+
discover_tools("aiecs.tools")
|
|
71
|
+
self._tools_discovered = True
|
|
72
|
+
logger.info("Tools discovered and registered")
|
|
73
|
+
|
|
74
|
+
# Initialize LLM manager (available in both modes)
|
|
75
|
+
self.llm_manager = LLMClientManager()
|
|
76
|
+
logger.info("LLM manager initialized")
|
|
77
|
+
|
|
78
|
+
if self.mode == "simple":
|
|
79
|
+
# Simple mode: only tools, no database/Celery
|
|
80
|
+
logger.info("Simple mode: tools only")
|
|
81
|
+
|
|
82
|
+
elif self.mode == "full":
|
|
83
|
+
# Full mode: with database and task queue
|
|
84
|
+
try:
|
|
85
|
+
# Check configuration first
|
|
86
|
+
validate_required_settings("database")
|
|
87
|
+
|
|
88
|
+
# Initialize database connection
|
|
89
|
+
from aiecs.infrastructure.persistence.database_manager import (
|
|
90
|
+
DatabaseManager,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
self.db_manager = DatabaseManager()
|
|
94
|
+
await self.db_manager.init_connection_pool()
|
|
95
|
+
logger.info("Database connection pool established")
|
|
96
|
+
|
|
97
|
+
# Initialize task manager
|
|
98
|
+
from aiecs.infrastructure.messaging.celery_task_manager import (
|
|
99
|
+
CeleryTaskManager,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
celery_config = {
|
|
103
|
+
"broker_url": self.settings.celery_broker_url,
|
|
104
|
+
"backend_url": self.settings.celery_broker_url,
|
|
105
|
+
}
|
|
106
|
+
self.task_manager = CeleryTaskManager(celery_config)
|
|
107
|
+
logger.info("Task manager initialized")
|
|
108
|
+
|
|
109
|
+
# Initialize operation executor
|
|
110
|
+
from aiecs.application.executors.operation_executor import (
|
|
111
|
+
OperationExecutor,
|
|
112
|
+
)
|
|
113
|
+
from aiecs.tools.tool_executor import ToolExecutor
|
|
114
|
+
from aiecs.utils.execution_utils import ExecutionUtils
|
|
115
|
+
|
|
116
|
+
tool_executor = ToolExecutor()
|
|
117
|
+
execution_utils = ExecutionUtils()
|
|
118
|
+
self.operation_executor = OperationExecutor(
|
|
119
|
+
tool_executor=tool_executor,
|
|
120
|
+
execution_utils=execution_utils,
|
|
121
|
+
config=self.config,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
except Exception as e:
|
|
125
|
+
logger.warning(f"Full mode initialization failed: {e}")
|
|
126
|
+
logger.info("Falling back to simple mode")
|
|
127
|
+
self.mode = "simple"
|
|
128
|
+
|
|
129
|
+
self._initialized = True
|
|
130
|
+
logger.info(f"AIECS client initialized successfully in {self.mode} mode")
|
|
131
|
+
|
|
132
|
+
except Exception as e:
|
|
133
|
+
logger.error(f"Failed to initialize AIECS: {e}")
|
|
134
|
+
raise
|
|
135
|
+
|
|
136
|
+
async def execute(self, context: TaskContext) -> Dict[str, Any]:
|
|
137
|
+
"""
|
|
138
|
+
Execute a task with the given context
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
context: TaskContext with task parameters
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
Task execution result
|
|
145
|
+
"""
|
|
146
|
+
if not self._initialized:
|
|
147
|
+
await self.initialize()
|
|
148
|
+
|
|
149
|
+
if self.mode == "simple":
|
|
150
|
+
# Simple mode: direct execution without queue
|
|
151
|
+
logger.info("Executing task in simple mode (direct execution)")
|
|
152
|
+
|
|
153
|
+
# Basic validation
|
|
154
|
+
try:
|
|
155
|
+
validate_required_settings("llm")
|
|
156
|
+
except ValueError as e:
|
|
157
|
+
return {
|
|
158
|
+
"status": "failed",
|
|
159
|
+
"error": f"LLM configuration required: {e}",
|
|
160
|
+
"mode": "simple",
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# TODO: Implement direct task execution without Celery
|
|
164
|
+
# For now, return a placeholder
|
|
165
|
+
return {
|
|
166
|
+
"status": "completed",
|
|
167
|
+
"result": "Simple mode execution (placeholder)",
|
|
168
|
+
"mode": "simple",
|
|
169
|
+
"context_id": context.user_id,
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
elif self.mode == "full":
|
|
173
|
+
if not self.task_manager:
|
|
174
|
+
raise RuntimeError("Task manager not initialized in full mode")
|
|
175
|
+
|
|
176
|
+
# Submit task to queue and get result
|
|
177
|
+
task_id = await self.task_manager.submit_task(context=context, task_type="task")
|
|
178
|
+
|
|
179
|
+
# Wait for task completion
|
|
180
|
+
result = await self._wait_for_task_completion(task_id)
|
|
181
|
+
return result
|
|
182
|
+
|
|
183
|
+
else:
|
|
184
|
+
raise ValueError(f"Unknown mode: {self.mode}")
|
|
185
|
+
|
|
186
|
+
async def execute_tool(self, tool_name: str, operation: str, params: Dict[str, Any]) -> Any:
|
|
187
|
+
"""
|
|
188
|
+
Execute a specific tool operation directly
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
tool_name: Name of the tool
|
|
192
|
+
operation: Operation to execute
|
|
193
|
+
params: Parameters for the operation
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
Operation result
|
|
197
|
+
"""
|
|
198
|
+
if not self._initialized:
|
|
199
|
+
await self.initialize()
|
|
200
|
+
|
|
201
|
+
# Get tool and execute directly (works in both modes)
|
|
202
|
+
tool = get_tool(tool_name)
|
|
203
|
+
if not tool:
|
|
204
|
+
raise ValueError(f"Tool '{tool_name}' not found")
|
|
205
|
+
|
|
206
|
+
# Prepare parameters with operation
|
|
207
|
+
tool_params = {**params, "op": operation}
|
|
208
|
+
|
|
209
|
+
# Execute tool
|
|
210
|
+
return await tool.execute(tool_params)
|
|
211
|
+
|
|
212
|
+
async def get_available_tools(self) -> List[Dict[str, Any]]:
|
|
213
|
+
"""Get list of all available tools"""
|
|
214
|
+
if not self._tools_discovered:
|
|
215
|
+
discover_tools("aiecs.tools")
|
|
216
|
+
self._tools_discovered = True
|
|
217
|
+
|
|
218
|
+
return list_tools()
|
|
219
|
+
|
|
220
|
+
async def get_tool(self, tool_name: str):
|
|
221
|
+
"""Get a specific tool instance"""
|
|
222
|
+
if not self._tools_discovered:
|
|
223
|
+
discover_tools("aiecs.tools")
|
|
224
|
+
self._tools_discovered = True
|
|
225
|
+
|
|
226
|
+
return get_tool(tool_name)
|
|
227
|
+
|
|
228
|
+
def process_task(self, task_context: TaskContext) -> Dict[str, Any]:
|
|
229
|
+
"""
|
|
230
|
+
Process a task synchronously (for compatibility with synchronous tool calls)
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
task_context: TaskContext containing the task data
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Task processing result with AI-generated response
|
|
237
|
+
"""
|
|
238
|
+
# Run the async method in a new event loop if needed
|
|
239
|
+
try:
|
|
240
|
+
loop = asyncio.get_event_loop()
|
|
241
|
+
if loop.is_running():
|
|
242
|
+
# If called from async context, create a new thread
|
|
243
|
+
import concurrent.futures
|
|
244
|
+
|
|
245
|
+
with concurrent.futures.ThreadPoolExecutor() as executor:
|
|
246
|
+
future = executor.submit(asyncio.run, self.process_task_async(task_context))
|
|
247
|
+
return future.result()
|
|
248
|
+
else:
|
|
249
|
+
# Run in current event loop
|
|
250
|
+
return loop.run_until_complete(self.process_task_async(task_context))
|
|
251
|
+
except RuntimeError:
|
|
252
|
+
# No event loop, create one
|
|
253
|
+
return asyncio.run(self.process_task_async(task_context))
|
|
254
|
+
|
|
255
|
+
async def process_task_async(self, task_context: TaskContext) -> Dict[str, Any]:
|
|
256
|
+
"""
|
|
257
|
+
Process a task asynchronously using AI providers
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
task_context: TaskContext containing the task data
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
Task processing result with AI-generated response
|
|
264
|
+
"""
|
|
265
|
+
if not self._initialized:
|
|
266
|
+
await self.initialize()
|
|
267
|
+
|
|
268
|
+
if not self.llm_manager:
|
|
269
|
+
raise RuntimeError("LLM manager not initialized")
|
|
270
|
+
|
|
271
|
+
try:
|
|
272
|
+
# Extract data from TaskContext
|
|
273
|
+
context_dict = task_context.to_dict()
|
|
274
|
+
metadata = context_dict.get("metadata", {})
|
|
275
|
+
|
|
276
|
+
# Get AI provider preference from metadata
|
|
277
|
+
ai_preference = metadata.get("aiPreference", "default")
|
|
278
|
+
provider = None
|
|
279
|
+
model = None
|
|
280
|
+
|
|
281
|
+
# Parse AI preference
|
|
282
|
+
if isinstance(ai_preference, str):
|
|
283
|
+
# Simple string preference
|
|
284
|
+
if ai_preference.lower() != "default":
|
|
285
|
+
try:
|
|
286
|
+
provider = AIProvider(ai_preference)
|
|
287
|
+
except ValueError:
|
|
288
|
+
logger.warning(f"Unknown AI provider: {ai_preference}, using default")
|
|
289
|
+
elif isinstance(ai_preference, dict):
|
|
290
|
+
# Dictionary with provider and model
|
|
291
|
+
provider_str = ai_preference.get("provider")
|
|
292
|
+
if provider_str:
|
|
293
|
+
try:
|
|
294
|
+
provider = AIProvider(provider_str)
|
|
295
|
+
except ValueError:
|
|
296
|
+
logger.warning(f"Unknown AI provider: {provider_str}, using default")
|
|
297
|
+
model = ai_preference.get("model")
|
|
298
|
+
|
|
299
|
+
# Build prompt from context data
|
|
300
|
+
# The prompt could come from various sources in the context
|
|
301
|
+
prompt = None
|
|
302
|
+
|
|
303
|
+
# Check for direct prompt in metadata
|
|
304
|
+
if "prompt" in metadata:
|
|
305
|
+
prompt = metadata["prompt"]
|
|
306
|
+
# Check for input_data (common in document generation)
|
|
307
|
+
elif "input_data" in context_dict:
|
|
308
|
+
input_data = context_dict["input_data"]
|
|
309
|
+
if isinstance(input_data, dict) and "prompt" in input_data:
|
|
310
|
+
prompt = input_data["prompt"]
|
|
311
|
+
elif isinstance(input_data, str):
|
|
312
|
+
prompt = input_data
|
|
313
|
+
|
|
314
|
+
if not prompt:
|
|
315
|
+
# Fallback: construct a simple prompt from available data
|
|
316
|
+
prompt = f"Task: {context_dict.get('task_type', 'general')}\nData: {context_dict}"
|
|
317
|
+
|
|
318
|
+
# Get temperature and other parameters from metadata
|
|
319
|
+
temperature = metadata.get("temperature", 0.7)
|
|
320
|
+
max_tokens = metadata.get("max_tokens", 2000)
|
|
321
|
+
|
|
322
|
+
# Generate text using LLM manager
|
|
323
|
+
messages = [LLMMessage(role="user", content=prompt)]
|
|
324
|
+
|
|
325
|
+
response = await self.llm_manager.generate_text(
|
|
326
|
+
messages=messages,
|
|
327
|
+
provider=provider,
|
|
328
|
+
model=model,
|
|
329
|
+
context=context_dict,
|
|
330
|
+
temperature=temperature,
|
|
331
|
+
max_tokens=max_tokens,
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
# Track model usage in context
|
|
335
|
+
if hasattr(task_context, "track_model_usage"):
|
|
336
|
+
task_context.track_model_usage(
|
|
337
|
+
model_id=response.model,
|
|
338
|
+
provider_id=response.provider,
|
|
339
|
+
mode="generate",
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
# Return result in expected format
|
|
343
|
+
return {
|
|
344
|
+
"status": "completed",
|
|
345
|
+
"response": response.content,
|
|
346
|
+
"provider": response.provider,
|
|
347
|
+
"model": response.model,
|
|
348
|
+
"tokens_used": response.tokens_used,
|
|
349
|
+
"cost_estimate": response.cost_estimate,
|
|
350
|
+
"context_id": context_dict.get("chat_id", "unknown"),
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
except Exception as e:
|
|
354
|
+
logger.error(f"Task processing failed: {e}", exc_info=True)
|
|
355
|
+
|
|
356
|
+
# For testing/development, provide a mock response when AI provider
|
|
357
|
+
# is unavailable
|
|
358
|
+
error_str = str(e).lower()
|
|
359
|
+
if "api key not configured" in error_str or "providernotavailable" in error_str:
|
|
360
|
+
logger.warning("AI provider unavailable, using mock response for testing")
|
|
361
|
+
mock_content = f"Mock AI-generated content for prompt: {prompt[:100] if len(prompt) > 100 else prompt}..."
|
|
362
|
+
return {
|
|
363
|
+
"status": "completed",
|
|
364
|
+
"response": mock_content,
|
|
365
|
+
"provider": "mock",
|
|
366
|
+
"model": "mock-model",
|
|
367
|
+
"tokens_used": len(mock_content.split()),
|
|
368
|
+
"cost_estimate": 0.0,
|
|
369
|
+
"context_id": context_dict.get("chat_id", "unknown"),
|
|
370
|
+
"mock": True,
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return {
|
|
374
|
+
"status": "failed",
|
|
375
|
+
"error": str(e),
|
|
376
|
+
"context_id": (
|
|
377
|
+
task_context.chat_id if hasattr(task_context, "chat_id") else "unknown"
|
|
378
|
+
),
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
async def _wait_for_task_completion(self, task_id: str, timeout: int = 300) -> Dict[str, Any]:
|
|
382
|
+
"""
|
|
383
|
+
Wait for task completion with timeout
|
|
384
|
+
|
|
385
|
+
Args:
|
|
386
|
+
task_id: Task ID to wait for
|
|
387
|
+
timeout: Maximum wait time in seconds
|
|
388
|
+
|
|
389
|
+
Returns:
|
|
390
|
+
Task result
|
|
391
|
+
"""
|
|
392
|
+
if not self.task_manager:
|
|
393
|
+
raise RuntimeError("Task manager not initialized")
|
|
394
|
+
|
|
395
|
+
start_time = asyncio.get_event_loop().time()
|
|
396
|
+
|
|
397
|
+
while True:
|
|
398
|
+
status = await self.task_manager.get_task_status(task_id)
|
|
399
|
+
|
|
400
|
+
if status.get("status") in ["completed", "failed", "cancelled"]:
|
|
401
|
+
return status
|
|
402
|
+
|
|
403
|
+
# Check timeout
|
|
404
|
+
if asyncio.get_event_loop().time() - start_time > timeout:
|
|
405
|
+
raise TimeoutError(f"Task {task_id} did not complete within {timeout} seconds")
|
|
406
|
+
|
|
407
|
+
# Wait before checking again
|
|
408
|
+
await asyncio.sleep(1)
|
|
409
|
+
|
|
410
|
+
async def close(self):
|
|
411
|
+
"""Close AIECS client and cleanup resources"""
|
|
412
|
+
logger.info("Shutting down AIECS client...")
|
|
413
|
+
|
|
414
|
+
if self.mode == "full" and self.db_manager:
|
|
415
|
+
try:
|
|
416
|
+
await self.db_manager.close_connection_pool()
|
|
417
|
+
logger.info("Database connection pool closed")
|
|
418
|
+
except Exception as e:
|
|
419
|
+
logger.error(f"Error closing database: {e}")
|
|
420
|
+
|
|
421
|
+
# Close all LLM clients
|
|
422
|
+
try:
|
|
423
|
+
await LLMClientFactory.close_all()
|
|
424
|
+
logger.info("LLM clients closed")
|
|
425
|
+
except Exception as e:
|
|
426
|
+
logger.error(f"Error closing LLM clients: {e}")
|
|
427
|
+
|
|
428
|
+
self._initialized = False
|
|
429
|
+
logger.info("AIECS client shutdown complete")
|
|
430
|
+
|
|
431
|
+
@asynccontextmanager
|
|
432
|
+
async def session(self):
|
|
433
|
+
"""Context manager for AIECS session"""
|
|
434
|
+
await self.initialize()
|
|
435
|
+
try:
|
|
436
|
+
yield self
|
|
437
|
+
finally:
|
|
438
|
+
await self.close()
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
# Convenience functions for quick usage
|
|
442
|
+
async def create_aiecs_client(
|
|
443
|
+
config: Optional[Dict[str, Any]] = None, mode: str = "simple"
|
|
444
|
+
) -> AIECS:
|
|
445
|
+
"""
|
|
446
|
+
Create and initialize an AIECS client
|
|
447
|
+
|
|
448
|
+
Args:
|
|
449
|
+
config: Optional configuration override
|
|
450
|
+
mode: Operation mode - "simple" or "full"
|
|
451
|
+
|
|
452
|
+
Returns:
|
|
453
|
+
Initialized AIECS client
|
|
454
|
+
"""
|
|
455
|
+
client = AIECS(config, mode)
|
|
456
|
+
await client.initialize()
|
|
457
|
+
return client
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
async def create_simple_client(
|
|
461
|
+
config: Optional[Dict[str, Any]] = None,
|
|
462
|
+
) -> AIECS:
|
|
463
|
+
"""Create a simple AIECS client (tools only, no database/Celery)"""
|
|
464
|
+
return await create_aiecs_client(config, "simple")
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
async def create_full_client(config: Optional[Dict[str, Any]] = None) -> AIECS:
|
|
468
|
+
"""Create a full AIECS client (with database and Celery)"""
|
|
469
|
+
return await create_aiecs_client(config, "full")
|